/*
 * Copyright (C) 2005 Johan Maasing johan at zoom.nu Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

package nu.zoom.swing.desktop;

import java.awt.Frame;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JMenuBar;

import nu.zoom.swing.desktop.statusbar.StatusBar;
import nu.zoom.swing.desktop.worker.EventQueuePolicy;
import nu.zoom.swing.desktop.worker.Policy;

/**
 * The primary service that displays and handles the main application frame.
 * <p>
 * A nice way to build applications that uses the workbench is to actually write
 * the application as one or more Workbench plug-ins.
 * </p>
 * <p>
 * Applications that use the workbench typically goes through the following
 * steps to start and display the application.
 * </p>
 * <ol>
 * <li>Obtain the workbench service from the gaderian registry.</li>
 * <li>Call start on the workbench and pass the registry reference to the
 * workbench. This will cause the workbench to load and initialize the plug-ins
 * and then start the GUI.</li>
 * </ol>
 * <p>
 * All methods are thread safe and may be called from any thread. Many of the
 * calls will schedule operations to occur on the AWT/Swing EventQueue and will
 * not return until those operations have finished.
 * </p>
 * 
 * @see nu.zoom.swing.desktop.PlugIn
 * @see nu.zoom.swing.desktop.WorkbenchListener
 */
public interface Workbench extends WorkbenchKeybinding {

	/**
	 * Add a listener for workbench events. If the listener is added during
	 * workbench start the added listener will NOT receive a start event from
	 * the workbench.
	 * 
	 * @param listener
	 *            The listener to register.
	 */
	public void addWorkBenchListener(WorkbenchListener listener);

	/**
	 * Remove a registered listener. Does nothing if the listener is not
	 * registered.
	 * 
	 * @param listener
	 *            The listener to remove.
	 */
	public void removeWorkBenchListener(WorkbenchListener listener);

	/**
	 * Add a listener that can prevent the workbench from closing.
	 * 
	 * @param listener
	 *            The listener to add.
	 */
	public void addCloseVetoListener(CloseVetoListener listener);

	/**
	 * Remove a previously added listener.
	 * 
	 * @param listener
	 *            The listener to remove.
	 */
	public void removeCloseVetoListener(CloseVetoListener listener);

	/**
	 * Set the title on the workbench window.
	 * 
	 * @param workbenchTitle
	 *            The new title for the frame
	 */
	@EventQueuePolicy(Policy.EVENT_QUEUE)
	public void setTitle(String workbenchTitle);

	/**
	 * Set the icon for the workbench window.
	 * 
	 * @param images
	 *            The icon(s) to use for the main application window.
	 */
	@EventQueuePolicy(Policy.EVENT_QUEUE)
	public void setIcon(List<ImageIcon> images);

	/**
	 * Creates a frame. The frame will be constructed and validated but will not
	 * be visible. By default it will be an JInternalFrame (attached mode)
	 * unless the frame has been remembered as detached.
	 * 
	 * @see javax.swing.JInternalFrame#JInternalFrame(java.lang.String, boolean,
	 *      boolean, boolean)
	 * @param preferenceKey
	 *            Used by the desktop to remember position and size of the
	 *            frames. May not be null or zero length.
	 * @param content
	 *            The gui component that is displayed in the frame.
	 * @param menu
	 *            The menubar to set for the frame. May be null which means that
	 *            there will not be any menu bar added to the frame.
	 * @param resizable
	 *            Should the internal frame be resizable
	 * @param maximizable
	 *            Should the internal frame be maximazible
	 * @return A new frame.
	 */
	@EventQueuePolicy(Policy.EVENT_QUEUE)
	public WorkbenchFrame createWorkbenchFrame(String preferenceKey, JComponent content, JMenuBar menu,
			boolean resizable, boolean maximizable);

	/**
	 * Creates a frame. The frame will be constructed and validated but will not
	 * be visible.
	 * 
	 * @see javax.swing.JInternalFrame#JInternalFrame(java.lang.String, boolean,
	 *      boolean, boolean)
	 * @param preferenceKey
	 *            Used by the desktop to remember position and size of the
	 *            frames. May not be null or zero length.
	 * @param content
	 *            The gui component that is displayed in the frame.
	 * @param menu
	 *            The menubar to set for the frame. May be null which means that
	 *            there will not be any menu bar added to the frame.
	 * @param resizable
	 *            Should the internal frame be resizable
	 * @param maximizable
	 *            Should the internal frame be maximazible
	 * @return A new frame.
	 */
	@EventQueuePolicy(Policy.EVENT_QUEUE)
	public WorkbenchFrame createWorkbenchFrame(String preferencesKey, JComponent content, JMenuBar menu,
			boolean resizable, boolean maximizable, boolean detached);

	/**
	 * Start the workbench. Will initalize and show the workbench. The workbench
	 * will call all registered listeners start method after the workbench has
	 * been constructed but before the workbench is displayed.
	 * 
	 * @see #close()
	 * @see WorkbenchListener#start()
	 */
	public void start();

	/**
	 * Restart the workbench. This will shut down and close all GUI elements and
	 * then restart the workbench. This is effectively the same as calling close
	 * followed by a start with the important distinction that restart will
	 * <emp>not </emp> drop registered listeners.
	 * 
	 * @see #close()
	 */
	@EventQueuePolicy(Policy.EVENT_QUEUE)
	public void restartGUI();

	/**
	 * Close all GUI elements and shutdown the workbench. The workbench will
	 * call the WokbenchListener to inform the application that it is shutting
	 * down. The workbench will drop all registered listeners after a call to
	 * close.
	 * 
	 * @see #restartGUI()
	 * @see WorkbenchListener#close()
	 */
	@EventQueuePolicy(Policy.EVENT_QUEUE)
	public void close();

	/**
	 * Get a handle to the workbench menubar.
	 * 
	 * @return The active menubar.
	 */
	public WorkbenchMenuBar getMenuBar();

	/**
	 * Get a factory that can show error dialogs in the workbench.
	 * 
	 * @return An instance of the error reporter.
	 */
	@EventQueuePolicy(Policy.EVENT_QUEUE)
	public ErrorReporter getErrorReporter();

	/**
	 * Dialogs that are opened by applications/plug-ins can use this method to
	 * set the owner of the dialog to the main frame.
	 * 
	 * @return The main frame of the application.
	 */
	public Frame getDialogOwner();

	/**
	 * Get the global status bar.
	 * 
	 * @return The desktop status bar.
	 */
	public StatusBar getStatusbar();
}